package xyz.hubery.model;

import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

@Data
public class Line {
    /**
     * 时间戳 (毫秒)
     */
    private Long timestamp;
    /**
     * 开盘价
     */
    private BigDecimal open;
    /**
     * 最高价
     */
    private BigDecimal high;
    /**
     * 最低价
     */
    private BigDecimal low;
    /**
     * 收盘价
     */
    private BigDecimal close;
    /**
     * 总交易量
     */
    private BigDecimal volume;

    public Line() {
    }

    /**
     * 通过价格构造
     */
    public Line(Long timestamp, BigDecimal price, BigDecimal volume) {
        this.timestamp = timestamp;
        this.open = price;
        this.high = price;
        this.low = price;
        this.close = price;
        this.volume = volume;
    }

    public Line(Long timestamp, BigDecimal open, BigDecimal high, BigDecimal low,
                BigDecimal close, BigDecimal volume) {
        this.timestamp = timestamp;
        this.open = open;
        this.high = high;
        this.low = low;
        this.close = close;
        this.volume = volume;
    }

    /**
     * 使用 LocalDateTime 构造（兼容现有代码）
     */
    public Line(LocalDateTime time, BigDecimal price, BigDecimal volume) {
        this.timestamp = time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        this.open = price;
        this.high = price;
        this.low = price;
        this.close = price;
        this.volume = volume;
    }

    // 从 JSON 字符串解析
    public Line(String klineData) {
        try {
            if (klineData.trim().startsWith("[")) {
                parseFromJsonArray(klineData);
            } else {
                parseFromJsonObject(klineData);
            }
        } catch (Exception e) {
            throw new RuntimeException("解析K线数据失败: " + klineData, e);
        }
    }

    private void parseFromJsonArray(String jsonArray) throws Exception {
        JSONArray array = JSONArray.parseArray(jsonArray);
        if (array.size() >= 6) {
            this.timestamp = array.getLong(0);
            this.open = array.getBigDecimal(1);
            this.high = array.getBigDecimal(2);
            this.low = array.getBigDecimal(3);
            this.close = array.getBigDecimal(4);
            this.volume = array.getBigDecimal(5);
        } else {
            throw new IllegalArgumentException("JSON数组元素不足");
        }
    }

    private void parseFromJsonObject(String jsonObject) throws Exception {
        com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
        Line temp = mapper.readValue(jsonObject, Line.class);
        this.timestamp = temp.timestamp;
        this.open = temp.open;
        this.high = temp.high;
        this.low = temp.low;
        this.close = temp.close;
        this.volume = temp.volume;
    }

    /**
     * 获取 LocalDateTime 对象
     */
    @JsonIgnore
    public LocalDateTime getTime() {
        return timestamp != null ?
                LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()) :
                null;
    }

    /**
     * 设置 LocalDateTime 对象
     */
    public void setTime(LocalDateTime time) {
        this.timestamp = time != null ?
                time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() :
                null;
    }

    /**
     * 格式化为 kline 数组格式
     */
    public String toKline() {
        JSONArray array = new JSONArray();
        array.add(timestamp);
        array.add(open);
        array.add(high);
        array.add(low);
        array.add(close);
        array.add(volume);
        return array.toJSONString();
    }

    /**
     * 获取格式化时间字符串
     */
    @JsonIgnore
    public String getFormattedTime() {
        if (timestamp == null) return "";
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault())
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}